using System;
using System.Collections.Generic;
using System.Text;
using System.Media;
using System.Xml;
using System.Xml.Serialization;
using System.Diagnostics;
using System.Reflection;
using Cancion.Figuras;
using System.Media;

namespace Cancion
{
    
    public abstract class Nota : IReproducible, IEquatable<Nota>, IComparable, ISerializable
    {
        protected SoundPlayer _tono;
        protected Figura _figura_musical;
	//	protected string _unaruta;
        protected int _escala;
        protected double _tiempoentrada;
		protected string _nombre;

        public Nota()
        {
        }
        
		public string GetNombre()
		{
			return _nombre;
		}

        //Emite el sonido de la nota correspondiente
        public void emitirsonido()
        {
            this._tono.Play();
        }

        public double TiempoEntrada
        {
            get { return this._tiempoentrada; }
        }

        public Figura GetFigura
        {
            get { return this._figura_musical; }
        }

        protected int Escala
        {
            get { return this._escala; }
        }

        //Verifica si la nota es igual a otra nota en funcion de la escala de las mismas
        public bool Equals(Nota otraNota)
        {
            return this._escala.Equals(otraNota.Escala);
        }
        
        //Compara dos notas en funcion de la escala
        public int CompareTo(object o)
        {
            if (this._escala < ((Nota)o).Escala) return -1;
            else if (this._escala > ((Nota)o).Escala) return 1;
            else return 0;
        }
        
        protected void setEscala(int e)
        {
            this._escala = e;
        }

        //Constructor que verifica si el tiempo de entrada es positivo
        public Nota(Figura unafigura, SoundPlayer sonido, double untiempoentrada, string nombre)
        {
			_nombre = nombre;

            if (untiempoentrada < 0)
                throw new System.ArgumentException("El tiempo de entrada de la nota debe ser positivo");
            else
            {
                this._escala = 0;
                this._figura_musical = unafigura;
                this._tono = sonido;
                this._tiempoentrada = untiempoentrada;
            }
        }

        //Le asigna a la nota la escala que la identifica con un numero que es mayor
        //a medida que aumenta la agudez de la nota
        protected abstract void AsignarEscala();


        public XmlNode Serializar(XmlDocument xmlDoc)
        {

            XmlElement childNode = xmlDoc.CreateElement("Nota");
            childNode.SetAttribute("tipo", (this.GetType()).ToString());
            childNode.SetAttribute("escala", this._escala.ToString());
            childNode.SetAttribute("tiempoentrada", (this._tiempoentrada).ToString());
            childNode.SetAttribute("nombre", (this._nombre.ToString()));
            string rutasonido="";
            try {
                rutasonido= this._tono.SoundLocation; }
            catch (Exception)
            {
            }
            childNode.SetAttribute("tono", rutasonido);
            XmlNode nodoFigura = (this._figura_musical).Serializar(xmlDoc);
            childNode.AppendChild(nodoFigura);

            return childNode;

        }


        public Object DesSerializar(XmlNode nodo)
        {
            //se leen los atributos del xml
            XmlAttributeCollection atributos = nodo.Attributes;
            string tipo = atributos.Item(0).Value;
            string escala = atributos.Item(1).Value;
            string tiempoentrada = atributos.Item(2).Value;
            string nombre = atributos.Item(3).Value;
            string tono = atributos.Item(4).Value;
            //............................................
            
            //Se obtiene la figura a partir del nodo figura del xml
            XmlNode nodoFigura = nodo.ChildNodes[0];
            Figura figurafalsa = new Negra();
            Figura fig = (Figura)figurafalsa.DesSerializar(nodoFigura);
            //......................................................

            //Se crea el soundplayer a partir de la ruta
            SoundPlayer sonido = new SoundPlayer(tono);
            //..........................................

            //Se crea la Nota
            Nota nota = (Nota)System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(tipo);
            nota._tono = sonido;
            nota._nombre = nombre;
            nota._escala = Convert.ToInt32(escala);
            nota._figura_musical = fig;
            nota._tiempoentrada = Convert.ToDouble(tiempoentrada);
            //.....................................................
            return nota;
        }

    }
}
